.PHONY:all clean test

ifeq ($(OS),Windows_NT)
    PATH_SEP := \\
else
    PATH_SEP := /
endif

BUILD_DIR=build
SRC_DIR=src
BUILD_SRC_DIR=$(BUILD_DIR)$(PATH_SEP)$(SRC_DIR)
SRC_C_FILES=$(wildcard $(SRC_DIR)/*.c)
SRC_FILE_NAMES=$(basename $(notdir $(SRC_C_FILES)))
SRC_OBJ_FILES=$(addprefix $(BUILD_SRC_DIR)$(PATH_SEP),$(addsuffix .obj,$(SRC_FILE_NAMES)))
LIB_NAME=lib
LIB_FILE=$(BUILD_DIR)$(PATH_SEP)$(LIB_NAME).dll

TEST_DIR=test
BUILD_TEST_DIR=$(BUILD_DIR)$(PATH_SEP)$(TEST_DIR)
#TEST_MAIN_FILES=${subst $(PATH_SEP),/,${shell findstr /M "main$(PATH_SEP)s*(" test$(PATH_SEP)*.c test$(PATH_SEP)*.cpp}}
TEST_C_FILES=$(basename $(notdir $(wildcard $(TEST_DIR)/*.c)))
TEST_C_WITH_MAIN_FILES=${basename ${notdir ${shell findstr /M "main$(PATH_SEP)s*(" test$(PATH_SEP)*.c}}}
TEST_C_WITHOUT_MAIN_FILES=$(filter-out $(TEST_C_WITH_MAIN_FILES),$(TEST_C_FILES))
TEST_C_OBJ_FILES=$(addprefix $(BUILD_TEST_DIR)$(PATH_SEP),$(addsuffix .obj,$(TEST_C_FILES)))
TEST_C_OBJ_WITHOUT_MAIN_FILES=$(addprefix $(BUILD_TEST_DIR)$(PATH_SEP),$(addsuffix .obj,$(TEST_C_WITHOUT_MAIN_FILES)))
TEST_C_EXE_FILES=$(addprefix $(BUILD_DIR)$(PATH_SEP),$(addsuffix .exe,$(TEST_C_WITH_MAIN_FILES)))
#TEST_C_EXE_FILES_PART=$(wordlist 1,2,$(TEST_C_EXE_FILES))

TEST_CPP_FILES=$(basename $(notdir $(wildcard $(TEST_DIR)/*.cpp)))
TEST_CPP_WITH_MAIN_FILES=${basename ${notdir ${shell findstr /M "main$(PATH_SEP)s*(" test$(PATH_SEP)*.cpp}}}
TEST_CPP_WITHOUT_MAIN_FILES=$(filter-out $(TEST_CPP_WITH_MAIN_FILES),$(TEST_CPP_FILES))
TEST_CPP_OBJ_FILES=$(addprefix $(BUILD_TEST_DIR)$(PATH_SEP),$(addsuffix .obj,$(TEST_CPP_FILES)))
TEST_CPP_OBJ_WITHOUT_MAIN_FILES=$(addprefix $(BUILD_TEST_DIR)$(PATH_SEP),$(addsuffix .obj,$(TEST_CPP_WITHOUT_MAIN_FILES)))
TEST_CPP_EXE_FILES=$(addprefix $(BUILD_DIR)$(PATH_SEP),$(addsuffix .exe,$(TEST_CPP_WITH_MAIN_FILES)))

all:$(BUILD_DIR) $(LIB_FILE) $(TEST_C_EXE_FILES) $(TEST_CPP_EXE_FILES)
	@echo Build Done

$(BUILD_DIR):
	mkdir $(BUILD_DIR)
	mkdir $(BUILD_SRC_DIR)
	mkdir $(BUILD_TEST_DIR)	

$(BUILD_SRC_DIR)$(PATH_SEP)%.obj:$(SRC_DIR)$(PATH_SEP)%.c
	gcc -c -o $@ $<

$(LIB_FILE):$(SRC_OBJ_FILES)
	gcc -shared -o $@ $^ 

$(BUILD_TEST_DIR)$(PATH_SEP)%.obj:$(TEST_DIR)$(PATH_SEP)%.c
	gcc -c -o $@ $< -I$(SRC_DIR)

$(BUILD_TEST_DIR)$(PATH_SEP)%.obj:$(TEST_DIR)$(PATH_SEP)%.cpp
	gcc -c -o $@ $< -I$(SRC_DIR)	

$(BUILD_DIR)$(PATH_SEP)%.exe:$(BUILD_TEST_DIR)$(PATH_SEP)%.obj $(TEST_C_OBJ_WITHOUT_MAIN_FILES) $(LIB_FILE) 
	gcc -o $@ $< $(TEST_C_OBJ_WITHOUT_MAIN_FILES) -L$(BUILD_DIR) -l$(LIB_NAME)

test:testc testcpp
#在命令前面加@，表示不显示命令本身，只显示命令的输出结果
	@echo Test Done 

testc:
	@echo Test C
#在命令前面加-，表示即使命令执行失败，也不退出make
	-@for %%i in ($(TEST_C_EXE_FILES)) do (echo %%i && %%i)

testcpp:
	@echo Test C++
	-@for %%i in ($(TEST_CPP_EXE_FILES)) do (echo %%i && %%i)

clean:
	ifeq ($(OS),Windows_NT)
		rd /s /q  $(BUILD_DIR)	
	else
		rm -rf $(BUILD_DIR)
	endif